// Copyright 2009 StarCite Inc.  All rights reserved.
// LinkedList.java 3:48:30 PM danny.liu
package com.billowsoft.lab.algorithm.linkedlist;

import java.util.Iterator;

/**
 * @author danny.liu Apr 24, 2012
 * @version 1.0
 * 
 */
public class LinkedList<T> implements Iterable<T> {

	private Node<T> startNode;

	public LinkedList(T[] nodes) {
		init(nodes);
	}
	
	private LinkedList(Node<T> startNode){
		this.startNode = startNode;
	}
	
	public LinkedList<T> reverseList(){
		Node<T> reversedStartNode = null;
		
		if(startNode != null){
			reversedStartNode = new Node<T>(startNode.getData(), null);
			Node<T> nextNode = startNode.getNext();
			while(nextNode != null){
				reversedStartNode = new Node<T>(nextNode.getData(), reversedStartNode);
				nextNode = nextNode.getNext();
			}
		}
		
		return new LinkedList<T>(reversedStartNode);
	}

	@Override
	public Iterator<T> iterator() {
		return new MyIterator(startNode);
	}

	class MyIterator implements Iterator<T> {

		Node<T> currentNode;

		MyIterator(Node<T> currentNode) {
			this.currentNode = currentNode;
		}

		@Override
		public boolean hasNext() {
			return currentNode != null;
		}

		@Override
		public T next() {
			try{
				return currentNode.getData();
			} finally{
				currentNode = currentNode.getNext();
			}
		}

		@Override
		public void remove() {
			throw new UnsupportedOperationException("Not supported now.");
		}

	}

	private void init(T[] nodes) {
		if (nodes == null) {
			return;
		}

		startNode = new Node<T>(nodes[0], null);
		Node<T> formerNode = startNode;
		for (int i = 1; i < nodes.length; i++) {
			Node<T> currentNode = new Node<T>(nodes[i], null);
			formerNode.setNext(currentNode);
			formerNode = currentNode;
		}
	}

}
